import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import mysql.connector
from mysql.connector import Error
import hashlib
import os
from PIL import Image, ImageTk, ImageDraw, ImageFont
import re
import random
import string
import io
import mainpage


class LoginApp:
    def __init__(self, root):
        self.root = root
        self.root.title("用户登录系统")
        window_width = 500
        window_height = 700
         # 获取屏幕尺寸
        screen_width = root.winfo_screenwidth()
        screen_height = root.winfo_screenheight()

        # 计算居中位置
        x_position = (screen_width - window_width) // 2
        y_position = (screen_height - window_height) // 2

        # 设置窗口位置和大小
        root.geometry(f"{window_width}x{window_height}+{x_position}+{y_position}")
        root.resizable(False, False)

        self.root.resizable(False, False)

        # 数据库连接配置 （请根据实际情况修改）
        self.db_config = {
            'host': 'localhost',        # 数据库主机地址
            'database': 'user_system',  # 数据库名称
            'user': 'root',             # 数据库用户名
            'password': '20040408'      # 数据库密码
        }

        # 当前用户信息
        self.current_user = None
        self.avatar_path = "ProfilePicture/default_avatar.jpg"
        self.avatar_data = None  # 存储头像二进制数据
        self.avatar_type = "jpeg"  # 头像类型
        self.captcha_text = ""  # 图形验证码文本

        # 创建界面
        self.create_login_frame()

# 在 LoginApp 类中，将 create_login_frame 方法修改为以下内容
    def create_login_frame(self):
        """创建登录界面"""
        self.clear_frame()

        # 登录框架
        login_frame = ttk.Frame(self.root, padding="30")
        login_frame.pack(fill=tk.BOTH, expand=True)

        # 标题
        title_label = ttk.Label(login_frame, text="用户登录", font=("Arial", 24, "bold"))
        title_label.pack(pady=(0, 30))

        # 手机号输入
        ttk.Label(login_frame, text="手机号:").pack(anchor=tk.W)
        self.username_entry = ttk.Entry(login_frame, font=("Arial", 12))
        self.username_entry.pack(fill=tk.X, pady=(0, 20))

        # 密码输入
        ttk.Label(login_frame, text="密码:").pack(anchor=tk.W)
        self.password_entry = ttk.Entry(login_frame, show="*", font=("Arial", 12))
        self.password_entry.pack(fill=tk.X, pady=(0, 20))

        # 图形验证码框架
        captcha_frame = ttk.Frame(login_frame)
        captcha_frame.pack(fill=tk.X, pady=(0, 20))

        ttk.Label(captcha_frame, text="验证码:").pack(anchor=tk.W)

        captcha_input_frame = ttk.Frame(captcha_frame)
        captcha_input_frame.pack(fill=tk.X)

        self.captcha_entry = ttk.Entry(captcha_input_frame, font=("Arial", 12))
        self.captcha_entry.pack(side=tk.LEFT, fill=tk.X, expand=True)

        refresh_btn = ttk.Button(captcha_input_frame, text="刷新", command=self.generate_captcha, width=8)
        refresh_btn.pack(side=tk.RIGHT, padx=(5, 0))

        self.captcha_canvas = tk.Canvas(captcha_frame, width=150, height=50, bg='white')
        self.captcha_canvas.pack(pady=(5, 0))

        self.generate_captcha()

        # 按钮框架
        button_frame = ttk.Frame(login_frame)
        button_frame.pack(fill=tk.X, pady=(20, 0))

        login_btn = ttk.Button(button_frame, text="登录", command=self.login)
        login_btn.pack(side=tk.LEFT, padx=(0, 10), fill=tk.X, expand=True)

        register_btn = ttk.Button(button_frame, text="注册", command=self.create_register_frame)
        register_btn.pack(side=tk.LEFT, fill=tk.X, expand=True)

        change_password_btn = ttk.Button(login_frame, text="忘记密码", command=self.create_change_password_frame)
        change_password_btn.pack(fill=tk.X, pady=(10, 0))

    def create_register_frame(self):
        """创建注册界面"""
        self.clear_frame()

        # 注册框架
        register_frame = ttk.Frame(self.root, padding="30")
        register_frame.pack(fill=tk.BOTH, expand=True)

        # 标题
        title_label = ttk.Label(register_frame, text="用户注册", font=("Arial", 20, "bold"))
        title_label.pack(pady=(0, 20))

        # 头像显示（可点击）
        self.avatar_canvas = tk.Canvas(register_frame, width=100, height=100, cursor="hand2")
        self.avatar_canvas.pack(pady=(0, 20))
        self.avatar_canvas.bind("<Button-1>", self.choose_avatar)  # 绑定点击事件
        self.display_avatar(self.avatar_path)

        # 提示标签
        avatar_tip = ttk.Label(register_frame, text="点击头像可更改", font=("Arial", 9), foreground="gray")
        avatar_tip.pack(pady=(0, 20))

        # 手机号输入（替换原来的用户名）
        ttk.Label(register_frame, text="手机号:").pack(anchor=tk.W)
        self.reg_username_entry = ttk.Entry(register_frame, font=("Arial", 12))
        self.reg_username_entry.pack(fill=tk.X, pady=(0, 10))

        # 用户名输入（新增）
        ttk.Label(register_frame, text="用户名:").pack(anchor=tk.W)
        self.reg_phone_entry = ttk.Entry(register_frame, font=("Arial", 12))
        self.reg_phone_entry.pack(fill=tk.X, pady=(0, 10))

        # 图形验证码框架
        captcha_frame = ttk.Frame(register_frame)
        captcha_frame.pack(fill=tk.X, pady=(0, 10))

        ttk.Label(captcha_frame, text="验证码:").pack(anchor=tk.W)

        captcha_input_frame = ttk.Frame(captcha_frame)
        captcha_input_frame.pack(fill=tk.X)

        self.reg_captcha_entry = ttk.Entry(captcha_input_frame, font=("Arial", 12))
        self.reg_captcha_entry.pack(side=tk.LEFT, fill=tk.X, expand=True)

        # 刷新验证码按钮
        refresh_btn = ttk.Button(captcha_input_frame, text="刷新", command=self.generate_captcha, width=8)
        refresh_btn.pack(side=tk.RIGHT, padx=(5, 0))

        # 验证码显示区域
        self.reg_captcha_canvas = tk.Canvas(captcha_frame, width=150, height=50, bg='white')
        self.reg_captcha_canvas.pack(pady=(5, 0))

        # 生成初始验证码
        self.generate_captcha()

        # 密码输入
        ttk.Label(register_frame, text="密码:").pack(anchor=tk.W)
        self.reg_password_entry = ttk.Entry(register_frame, show="*", font=("Arial", 12))
        self.reg_password_entry.pack(fill=tk.X, pady=(0, 10))

        # 确认密码输入
        ttk.Label(register_frame, text="确认密码:").pack(anchor=tk.W)
        self.reg_confirm_password_entry = ttk.Entry(register_frame, show="*", font=("Arial", 12))
        self.reg_confirm_password_entry.pack(fill=tk.X, pady=(0, 20))

        # 按钮框架
        button_frame = ttk.Frame(register_frame)
        button_frame.pack(fill=tk.X)

        # 注册按钮
        register_btn = ttk.Button(button_frame, text="注册", command=self.register)
        register_btn.pack(side=tk.LEFT, padx=(0, 10), fill=tk.X, expand=True)

        # 返回登录按钮
        back_btn = ttk.Button(button_frame, text="返回登录", command=self.create_login_frame)
        back_btn.pack(side=tk.LEFT, fill=tk.X, expand=True)

    def create_change_password_frame(self):
        """创建修改密码界面"""
        self.clear_frame()

        # 修改密码框架
        change_frame = ttk.Frame(self.root, padding="30")
        change_frame.pack(fill=tk.BOTH, expand=True)

        # 标题
        title_label = ttk.Label(change_frame, text="修改密码", font=("Arial", 20, "bold"))
        title_label.pack(pady=(0, 20))

        # 手机号输入（替换原来的用户名）
        ttk.Label(change_frame, text="手机号:").pack(anchor=tk.W)
        self.change_username_entry = ttk.Entry(change_frame, font=("Arial", 12))
        self.change_username_entry.pack(fill=tk.X, pady=(0, 10))

        # 用户名输入（新增，可选）
        ttk.Label(change_frame, text="用户名:").pack(anchor=tk.W)
        self.change_phone_entry = ttk.Entry(change_frame, font=("Arial", 12))
        self.change_phone_entry.pack(fill=tk.X, pady=(0, 10))

        # 图形验证码框架
        captcha_frame = ttk.Frame(change_frame)
        captcha_frame.pack(fill=tk.X, pady=(0, 10))

        ttk.Label(captcha_frame, text="验证码:").pack(anchor=tk.W)

        captcha_input_frame = ttk.Frame(captcha_frame)
        captcha_input_frame.pack(fill=tk.X)

        self.change_captcha_entry = ttk.Entry(captcha_input_frame, font=("Arial", 12))
        self.change_captcha_entry.pack(side=tk.LEFT, fill=tk.X, expand=True)

        # 刷新验证码按钮
        refresh_btn = ttk.Button(captcha_input_frame, text="刷新", command=self.generate_captcha, width=8)
        refresh_btn.pack(side=tk.RIGHT, padx=(5, 0))

        # 验证码显示区域
        self.change_captcha_canvas = tk.Canvas(captcha_frame, width=150, height=50, bg='white')
        self.change_captcha_canvas.pack(pady=(5, 0))

        # 生成初始验证码
        self.generate_captcha()

        # 新密码输入
        ttk.Label(change_frame, text="新密码:").pack(anchor=tk.W)
        self.new_password_entry = ttk.Entry(change_frame, show="*", font=("Arial", 12))
        self.new_password_entry.pack(fill=tk.X, pady=(0, 10))

        # 确认新密码输入
        ttk.Label(change_frame, text="确认新密码:").pack(anchor=tk.W)
        self.confirm_new_password_entry = ttk.Entry(change_frame, show="*", font=("Arial", 12))
        self.confirm_new_password_entry.pack(fill=tk.X, pady=(0, 20))

        # 按钮框架
        button_frame = ttk.Frame(change_frame)
        button_frame.pack(fill=tk.X)

        # 修改密码按钮
        change_btn = ttk.Button(button_frame, text="修改密码", command=self.change_password)
        change_btn.pack(side=tk.LEFT, padx=(0, 10), fill=tk.X, expand=True)

        # 返回登录按钮
        back_btn = ttk.Button(button_frame, text="返回登录", command=self.create_login_frame)
        back_btn.pack(side=tk.LEFT, fill=tk.X, expand=True)

    # login方法修改
    def register(self):
        phone = self.reg_username_entry.get().strip()  # 改为手机号
        username = self.reg_phone_entry.get().strip()  # 新增用户名字段
        password = self.reg_password_entry.get().strip()
        confirm_password = self.reg_confirm_password_entry.get().strip()
        captcha = self.reg_captcha_entry.get().strip()

        # 输入验证
        if not phone or not username or not password or not confirm_password or not captcha:
            messagebox.showerror("错误", "请填写所有字段")
            return

        # 验证图形验证码
        if not self.validate_captcha(captcha):
            messagebox.showerror("错误", "验证码错误")
            self.generate_captcha()  # 刷新验证码
            self.reg_captcha_entry.delete(0, tk.END)
            return

        # 验证手机号格式
        if not re.match(r'^1[3-9]\d{9}$', phone):
            messagebox.showerror("错误", "请输入正确的手机号格式")
            return

        # 验证密码一致性
        if password != confirm_password:
            messagebox.showerror("错误", "两次输入的密码不一致")
            return

        # 验证密码强度
        password_errors = self.validate_password_strength(password)
        if password_errors:
            error_message = "\n".join(password_errors)
            messagebox.showerror("密码强度不足", error_message)
            return

        # 连接数据库
        connection = self.connect_database()
        if not connection:
            return

        try:
            cursor = connection.cursor()

            # 检查手机号是否已存在
            check_query = "SELECT id FROM users WHERE phone = %s"
            cursor.execute(check_query, (phone,))
            if cursor.fetchone():
                messagebox.showerror("错误", "手机号已注册，请使用其他手机号")
                self.generate_captcha()  # 刷新验证码
                return

            # 检查用户名是否已存在
            check_query = "SELECT id FROM users WHERE username = %s"
            cursor.execute(check_query, (username,))
            if cursor.fetchone():
                messagebox.showerror("错误", "用户名已存在，请选择其他用户名")
                self.generate_captcha()  # 刷新验证码
                return

            # 插入新用户，包括头像数据
            insert_query = "INSERT INTO users (avatar_path, avatar_data, avatar_type, username, phone, password) VALUES (%s, %s, %s, %s, %s, %s)"
            cursor.execute(insert_query, (
                self.avatar_path,  # 使用当前的 avatar_path
                self.avatar_data,  # 使用二进制数据
                self.avatar_type,  # 使用文件类型
                username,  # 用户名
                phone,     # 手机号
                self.hash_password(password)
            ))
            connection.commit()

            messagebox.showinfo("成功", "注册成功！现在可以登录了")
            self.create_login_frame()

        except Error as e:
            messagebox.showerror("数据库错误", f"注册时发生错误: {e}")
        finally:
            if connection.is_connected():
                cursor.close()
                connection.close()

    def validate_password_strength(self, password):
        errors = []

        # 检查密码长度
        if len(password) < 6:
            errors.append("密码长度必须大于等于6")

        # 检查是否包含大写字母
        if not re.search(r'[A-Z]', password):
            errors.append("密码必须包含大写字母")

        # 检查是否包含小写字母
        if not re.search(r'[a-z]', password):
            errors.append("密码必须包含小写字母")

        # 检查是否包含数字
        if not re.search(r'\d', password):
            errors.append("密码必须包含数字")

        # 检查是否包含特殊字符
        if not re.search(r'[!@#$%^&*(),.?":{}|<>[\]\\;\'`~+=/_-]', password):
            errors.append("密码必须包含特殊字符")

        return errors
    # register方法修改
    def register(self):
        """用户注册"""
        phone = self.reg_username_entry.get().strip()  # 改为手机号
        username = self.reg_phone_entry.get().strip()  # 新增用户名字段
        password = self.reg_password_entry.get().strip()
        confirm_password = self.reg_confirm_password_entry.get().strip()
        captcha = self.reg_captcha_entry.get().strip()

        # 输入验证
        if not phone or not username or not password or not confirm_password or not captcha:
            messagebox.showerror("错误", "请填写所有字段")
            return

        # 验证图形验证码
        if not self.validate_captcha(captcha):
            messagebox.showerror("错误", "验证码错误")
            self.generate_captcha()  # 刷新验证码
            self.reg_captcha_entry.delete(0, tk.END)
            return

        # 验证手机号格式
        if not re.match(r'^1[3-9]\d{9}$', phone):
            messagebox.showerror("错误", "请输入正确的手机号格式")
            return

        # 验证密码一致性
        if password != confirm_password:
            messagebox.showerror("错误", "两次输入的密码不一致")
            return

        # 验证密码强度
        password_errors = self.validate_password_strength(password)
        if password_errors:
            error_message = "\n".join(password_errors)
            messagebox.showerror("密码强度不足", error_message)
            return

        # 连接数据库
        connection = self.connect_database()
        if not connection:
            return

        try:
            cursor = connection.cursor()

            # 检查手机号是否已存在
            check_query = "SELECT id FROM users WHERE phone = %s"
            cursor.execute(check_query, (phone,))
            if cursor.fetchone():
                messagebox.showerror("错误", "手机号已注册，请使用其他手机号")
                self.generate_captcha()  # 刷新验证码
                return

            # 检查用户名是否已存在
            check_query = "SELECT id FROM users WHERE username = %s"
            cursor.execute(check_query, (username,))
            if cursor.fetchone():
                messagebox.showerror("错误", "用户名已存在，请选择其他用户名")
                self.generate_captcha()  # 刷新验证码
                return

            # 插入新用户，包括头像数据
            insert_query = "INSERT INTO users (avatar_path, avatar_data, avatar_type, username, phone, password) VALUES (%s, %s, %s, %s, %s, %s)"
            cursor.execute(insert_query, (
                self.avatar_path,
                self.avatar_data,
                self.avatar_type,
                username,  # 用户名
                phone,     # 手机号
                self.hash_password(password)
            ))
            connection.commit()

            messagebox.showinfo("成功", "注册成功！现在可以登录了")
            self.create_login_frame()

        except Error as e:
            messagebox.showerror("数据库错误", f"注册时发生错误: {e}")
        finally:
            if connection.is_connected():
                cursor.close()
                connection.close()
# change_password方法修改
    def change_password(self):
        """修改密码"""
        phone = self.change_username_entry.get().strip()  # 改为手机号
        username = self.change_phone_entry.get().strip()  # 新增用户名字段
        new_password = self.new_password_entry.get().strip()
        confirm_new_password = self.confirm_new_password_entry.get().strip()
        captcha = self.change_captcha_entry.get().strip()

        # 输入验证
        if not phone or not new_password or not confirm_new_password or not captcha:
            messagebox.showerror("错误", "请填写手机号、新密码和验证码")
            return

        # 验证图形验证码
        if not self.validate_captcha(captcha):
            messagebox.showerror("错误", "验证码错误")
            self.generate_captcha()  # 刷新验证码
            self.change_captcha_entry.delete(0, tk.END)
            return

        # 验证手机号格式
        if not re.match(r'^1[3-9]\d{9}$', phone):
            messagebox.showerror("错误", "请输入正确的手机号格式")
            return

        # 验证密码一致性
        if new_password != confirm_new_password:
            messagebox.showerror("错误", "两次输入的新密码不一致")
            return

        # 验证新密码强度
        password_errors = self.validate_password_strength(new_password)
        if password_errors:
            error_message = "\n".join(password_errors)
            messagebox.showerror("密码强度不足", error_message)
            return

        # 连接数据库
        connection = self.connect_database()
        if not connection:
            return

        try:
            cursor = connection.cursor()

            # 验证用户是否存在
            check_query = "SELECT id FROM users WHERE phone = %s"
            cursor.execute(check_query, (phone,))
            user = cursor.fetchone()

            if not user:
                messagebox.showerror("错误", "用户不存在，请检查手机号")
                self.generate_captcha()  # 刷新验证码
                return

            # 更新密码
            update_query = "UPDATE users SET password = %s WHERE phone = %s"
            cursor.execute(update_query, (self.hash_password(new_password), phone))
            connection.commit()

            messagebox.showinfo("成功", "密码修改成功！")
            self.create_login_frame()

        except Error as e:
            messagebox.showerror("数据库错误", f"修改密码时发生错误: {e}")
        finally:
            if connection.is_connected():
                cursor.close()
                connection.close()

    def clear_frame(self):
        """清空当前界面"""
        for widget in self.root.winfo_children():
            widget.destroy()

    def generate_captcha(self):
        """生成图形验证码"""
        # 生成4位随机字符（字母+数字）
        self.captcha_text = ''.join(random.choices(string.ascii_uppercase + string.digits, k=4))

        # 创建图像
        image = Image.new('RGB', (150, 50), color=(255, 255, 255))
        draw = ImageDraw.Draw(image)

        # 添加干扰线
        for _ in range(8):
            x1 = random.randint(0, 150)
            y1 = random.randint(0, 50)
            x2 = random.randint(0, 150)
            y2 = random.randint(0, 50)
            draw.line([(x1, y1), (x2, y2)], fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)), width=1)

        # 绘制验证码字符
        try:
            # 尝试使用系统字体
            font = ImageFont.truetype("arial.ttf", 28)
        except:
            # 如果没有找到字体，使用默认字体
            font = ImageFont.load_default()

        # 绘制每个字符
        for i, char in enumerate(self.captcha_text):
            x = 15 + i * 30
            y = random.randint(5, 15)
            draw.text((x, y), char, font=font, fill=(random.randint(0, 100), random.randint(0, 100), random.randint(0, 100)))

        # 添加噪点
        for _ in range(150):
            x = random.randint(0, 150)
            y = random.randint(0, 50)
            draw.point((x, y), fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))

        # 转换为tkinter可用格式
        self.captcha_image = ImageTk.PhotoImage(image)

        # 在对应的画布上显示验证码
        if hasattr(self, 'captcha_canvas') and self.captcha_canvas.winfo_exists():
            self.captcha_canvas.delete("all")
            self.captcha_canvas.create_image(75, 25, image=self.captcha_image)
        elif hasattr(self, 'reg_captcha_canvas') and self.reg_captcha_canvas.winfo_exists():
            self.reg_captcha_canvas.delete("all")
            self.reg_captcha_canvas.create_image(75, 25, image=self.captcha_image)
        elif hasattr(self, 'change_captcha_canvas') and self.change_captcha_canvas.winfo_exists():
            self.change_captcha_canvas.delete("all")
            self.change_captcha_canvas.create_image(75, 25, image=self.captcha_image)

    def validate_captcha(self, input_captcha):
        """验证图形验证码"""
        return input_captcha.upper() == self.captcha_text.upper()

    def display_avatar(self, image_path=None):
        """显示圆形头像"""
        try:
            # 如果有头像二进制数据，优先使用
            if self.avatar_data:
                # 从二进制数据创建图像
                image_stream = io.BytesIO(self.avatar_data)
                image = Image.open(image_stream)
            else:
                # 否则从文件路径加载
                image = Image.open(image_path) if image_path else Image.open("ProfilePicture/default_avatar.jpg")

            image = image.resize((100, 100), Image.LANCZOS)

            # 创建圆形遮罩
            mask = Image.new('L', (100, 100), 0)
            from PIL import ImageDraw
            draw = ImageDraw.Draw(mask)
            draw.ellipse((0, 0, 100, 100), fill=255)

            # 应用遮罩创建圆形图像
            output = Image.new('RGBA', (100, 100), (0, 0, 0, 0))
            image = image.convert("RGBA")
            output.paste(image, mask=mask)

            # 转换为tkinter可用格式
            self.avatar_image = ImageTk.PhotoImage(output)
            self.avatar_canvas.delete("all")  # 清除之前的内容
            self.avatar_canvas.create_image(50, 50, image=self.avatar_image)
        except Exception as e:
            # 如果加载失败，显示默认头像
            self.avatar_canvas.delete("all")
            self.avatar_canvas.create_oval(10, 10, 90, 90, fill="gray")
            self.avatar_canvas.create_text(50, 50, text="头像", fill="white")

    def choose_avatar(self, event=None):
        """选择头像"""
        file_path = filedialog.askopenfilename(
            title="选择头像",
            filetypes=[("Image files", "*.jpg *.jpeg *.png *.gif")]
        )
        if file_path:
            try:
                # 打开头像文件并读取二进制数据
                with open(file_path, 'rb') as f:
                    self.avatar_data = f.read()

                # 获取文件扩展名作为类型
                _, ext = os.path.splitext(file_path)
                self.avatar_type = ext.lower().replace('.', '')

                # 更新 avatar_path 为实际文件路径
                self.avatar_path = file_path

                # 显示头像
                self.display_avatar_from_data()

            except Exception as e:
                messagebox.showerror("错误", f"读取头像文件失败: {str(e)}")
                self.avatar_data = None


    def display_avatar_from_data(self):
        """从二进制数据显示头像"""
        if self.avatar_data:
            try:
                # 从二进制数据创建图像
                image_stream = io.BytesIO(self.avatar_data)
                image = Image.open(image_stream)
                image = image.resize((100, 100), Image.LANCZOS)

                # 创建圆形遮罩
                mask = Image.new('L', (100, 100), 0)
                from PIL import ImageDraw
                draw = ImageDraw.Draw(mask)
                draw.ellipse((0, 0, 100, 100), fill=255)

                # 应用遮罩创建圆形图像
                output = Image.new('RGBA', (100, 100), (0, 0, 0, 0))
                image = image.convert("RGBA")
                output.paste(image, mask=mask)

                # 转换为tkinter可用格式
                self.avatar_image = ImageTk.PhotoImage(output)
                self.avatar_canvas.delete("all")
                self.avatar_canvas.create_image(50, 50, image=self.avatar_image)
            except Exception as e:
                # 如果处理失败，显示默认头像
                self.avatar_canvas.delete("all")
                self.avatar_canvas.create_oval(10, 10, 90, 90, fill="gray")
                self.avatar_canvas.create_text(50, 50, text="头像", fill="white")

    def hash_password(self, password):
        """对密码进行哈希处理"""
        return hashlib.sha256(password.encode()).hexdigest()

    def connect_database(self):
        """
        连接数据库
        注意：请根据实际情况修改 db_config 中的数据库连接参数
        - host: 数据库服务器地址
        - database: 数据库名称
        - user: 数据库用户名
        - password: 数据库密码
        """
        try:
            connection = mysql.connector.connect(**self.db_config)
            return connection
        except Error as e:
            messagebox.showerror("数据库错误", f"无法连接到数据库: {e}")
            return None
    def login(self):
        """用户登录"""
        phone = self.username_entry.get().strip()  # 改为手机号
        password = self.password_entry.get().strip()
        captcha = self.captcha_entry.get().strip()

        # 输入验证
        if not phone or not password or not captcha:
            messagebox.showerror("错误", "请输入手机号、密码和验证码")
            return

        # 验证手机号格式
        if not re.match(r'^1[3-9]\d{9}$', phone):
            messagebox.showerror("错误", "请输入正确的手机号格式")
            return

        # 验证图形验证码
        if not self.validate_captcha(captcha):
            messagebox.showerror("错误", "验证码错误")
            self.generate_captcha()  # 刷新验证码
            self.captcha_entry.delete(0, tk.END)
            return

        # 连接数据库
        connection = self.connect_database()
        if not connection:
            return

        try:
            cursor = connection.cursor(dictionary=True)

            # 查询用户信息，包括头像数据（使用手机号查询）
            query = "SELECT * FROM users WHERE phone = %s AND password = %s"
            cursor.execute(query, (phone, self.hash_password(password)))
            user = cursor.fetchone()

            if user:
                # 保存用户信息和头像数据
                self.current_user = user
                self.avatar_data = user.get('avatar_data')
                self.avatar_type = user.get('avatar_type', 'jpeg')

                messagebox.showinfo("成功", f"欢迎, {user.get('username', phone)}!")
                # 跳转到主界面
                self.root.withdraw()  # 隐藏登录窗口
                main_app = mainpage.AIApplication()  # 创建主应用窗口
                self.main_app = main_app
            else:
                messagebox.showerror("错误", "手机号或密码错误，请检查后重试或注册新账号")
                self.generate_captcha()  # 刷新验证码

        except Error as e:
            messagebox.showerror("数据库错误", f"登录时发生错误: {e}")
        finally:
            if connection.is_connected():
                cursor.close()
                connection.close()

if __name__ == "__main__":
    root = tk.Tk()
    app = LoginApp(root)
    root.mainloop()